//value:data数据
//vm:vm实例对象
function observe(value, vm) {
  //看门狗  咬逻辑
  if (!value || typeof value !== 'object') {
    return;
  }
  return new Observer(value);
}

function Observer(data) {
  //this:Observer实例对象
  this.data = data;
  this.walk(data);
}

Observer.prototype = {
  walk: function (data) {
    var me = this;
    Object.keys(data).forEach(function (key) {
      //key : data中一个个可枚举属性的名称
      me.convert(key, data[key]);
    });
  },

  convert: function (key, val) {
    //{key:val} : data中的属性名和属性值键值对!
    this.defineReactive(this.data, key, val);
  },
  defineReactive: function (data, key, val) {
    //dep实例  每一个data中的属性都会分配到一个dep
    var dep = new Dep();

    //递归
    var childObj = observe(val);

    //数据劫持
    Object.defineProperty(data, key, {
      enumerable: true, // 可枚举
      configurable: false, // 不能再define
      get: function () {
        if (Dep.target) {
          dep.depend();
        }
        return val;
      },
      set: function (newVal) {
        if (newVal === val) {
          return;
        }
        val = newVal;
        childObj = observe(newVal);

        //执行响应式更新!!!
        dep.notify();
      },
    });
  },
};

var uid = 0;

function Dep() {
  this.id = uid++;
  this.subs = [];
}

Dep.prototype = {
  addSub: function (sub) {
    //存放dep关联的watcher实例!
    this.subs.push(sub);
  },

  depend: function () {
    //Dep.target: 当前正在解析的指令所对应的watcher实例!!
    //this: watcher实例所关联的dep!!
    Dep.target.addDep(this);
  },

  notify: function () {
    this.subs.forEach(function (sub) {
      sub.update();
    });
  },
};

Dep.target = null;
